
#include <vector>
#include <memory>

#include "stm32f4xx_hal.h"
#include "board.h"

#define LED0_PORT    GPIOE
#define LED0_PIN     GPIO_PIN_3
#define LED1_PORT    GPIOE
#define LED1_PIN     GPIO_PIN_4
#define LED2_PORT    GPIOG
#define LED2_PIN     GPIO_PIN_9

class Led {

public:
    Led(GPIO_TypeDef *port, uint16_t pin) :
        port(port), pin(pin)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.Pin = pin;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = 0;
        HAL_GPIO_Init(port, &GPIO_InitStruct);
    }

    ~Led()
    {
        HAL_GPIO_DeInit(port, pin);
    }

    void on()
    {
        HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET);
    }

    void off()
    {
        HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET);
    }

    void toggle()
    {
        HAL_GPIO_TogglePin(port, pin);
    }

private:
    GPIO_TypeDef * port;
    uint16_t pin;
};

extern "C" int main()
{
    HAL_Init();
    SystemClock_Config();

    std::vector<std::shared_ptr<Led>> leds;
    auto led0 = std::make_shared<Led>(LED0_PORT, LED0_PIN);
    leds.push_back(led0);
    auto led1 = std::make_shared<Led>(LED1_PORT, LED1_PIN);
    leds.push_back(led1);
    auto led2 = std::make_shared<Led>(LED2_PORT, LED2_PIN);
    leds.push_back(led2);

    while (1)
    {
        for (auto &led : leds) {
            led->toggle();
        }
        HAL_Delay(500);
    }

    return 0;
}

extern "C" void SysTick_Handler(void)
{
    HAL_IncTick();
}
